package com.ruizhong.centercontroll.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruizhong.centercontroll.dao.TButtonMapper;
import com.ruizhong.centercontroll.entity.TButton;
import com.ruizhong.centercontroll.entity.TCommand;
import com.ruizhong.centercontroll.service.TButtonService;
import com.ruizhong.centercontroll.service.TCommandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TButtonServiceImpl extends ServiceImpl<TButtonMapper, TButton> implements TButtonService {


    @Autowired
    private TCommandService tCommandService;


    @Override
    public void saveNewButton(TButton tButton) {
        save(tButton);
    }


    /**
     * @author: fengweijie
     * @methodsName: saveNewButtonList
     * @description: 保存当前页面的按钮列表
     * @param: buttonList，pageId
     * @return: void
     * @throws:
     */
    @Override
    @Transactional
    public void saveNewButtonList(List<Map<String, Object>> buttonList, Integer pageId, boolean isNew) {
        deleteButtonByPageId(pageId);
        final HashMap<Integer, List<Map<String, Object>>> buttonIdMapClickCommandList = new HashMap<>();
        final HashMap<Integer, List<Map<String, Object>>> buttonIdMapInitCommandList = new HashMap<>();
        buttonList.forEach(buttonOb -> {
            Object textChinese = buttonOb.get("textChinese");
            Object textTraditional = buttonOb.get("textTraditional");
            Object textEnglish = buttonOb.get("textEnglish");
            Object background = buttonOb.get("background");
            Object fontColor = buttonOb.get("fontColor");
            Object backgroundColor = buttonOb.get("backgroundColor");
            Object borderCorner = buttonOb.get("borderCorner");
            Object name = buttonOb.get("name");
            TButton tButton = new TButton();
            tButton.setPageId(pageId);
            tButton.setTextChinese(textChinese == null ? null : textChinese.toString());
            tButton.setTextTraditional(textTraditional == null ? null : textTraditional.toString());
            tButton.setTextEnglish(textEnglish == null ? null : textEnglish.toString());
            tButton.setName(name.toString());
            tButton.setBackground(background == null ? null : background.toString());
            tButton.setFontSize(Integer.parseInt(buttonOb.get("fontSize").toString()));
            tButton.setW(Double.parseDouble(buttonOb.get("w").toString()));
            tButton.setH(Double.parseDouble(buttonOb.get("h").toString()));
            tButton.setX(buttonOb.get("x") == null?0:Double.parseDouble(buttonOb.get("x").toString()));
            tButton.setY(buttonOb.get("y") == null?0:Double.parseDouble(buttonOb.get("y").toString()));
            tButton.setZ(Integer.parseInt(buttonOb.get("z").toString()));
            tButton.setFontColor(fontColor == null ? null : fontColor.toString());
            Object displayVariableName = buttonOb.get("displayVariableName");
            Object displayVariableValue = buttonOb.get("displayVariableValue");
            tButton.setDisplayVariableName(displayVariableName == null ? null : displayVariableName.toString());
            tButton.setDisplayVariableValue(displayVariableValue == null ? null : displayVariableValue.toString());
            tButton.setBackgroundColor(backgroundColor == null ? null : backgroundColor.toString());
            tButton.setBorderCorner(borderCorner == null ? null : Integer.parseInt(borderCorner.toString()));
            Object conditionShow = buttonOb.get("conditionShow");
            tButton.setConditionShowData(conditionShow == null ? null : (Boolean) conditionShow ? 1 : 0);
            List<String> addedButtonGroupArr = (List<String>) buttonOb.get("addedButtonGroupArr");
            Map logicGraph = (Map) buttonOb.get("logicGraph");
            List<Map<String, Object>> clickCommandList = null;
            List<Map<String, Object>> initCommandList = null;
            if (!isNew) {
                clickCommandList = (List<Map<String, Object>>) buttonOb.get("clickCommandList");
                initCommandList = (List<Map<String, Object>>) buttonOb.get("initCommandList");
            } else {
                ObjectMapper mapper = new ObjectMapper();
                try {
                    String logicGraphString = mapper.writeValueAsString(logicGraph);
                    tButton.setLogicGraphData(logicGraphString);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                Map<String, List> typeMapCommandList = TCommandServiceImpl.getCommandsByGraph(logicGraph);
                clickCommandList = typeMapCommandList.get("releaseCommandList");
                initCommandList = typeMapCommandList.get("initCommandList");
            }
            Boolean chooseGroup = false;
            if (!CollectionUtils.isEmpty(clickCommandList)) {
                for (Map<String, Object> stringObjectMap : clickCommandList) {
                    Object commandEventType = stringObjectMap.get("eventType");
                    String eventType = commandEventType == null ? null : commandEventType.toString();
                    if ("4".equals(eventType)) {
                        chooseGroup = true;
                    }
                }
            }
            if (!CollectionUtils.isEmpty(addedButtonGroupArr) && !chooseGroup) {
                StringBuilder addedButtonGroupArrData = new StringBuilder();
                for (String s : addedButtonGroupArr) {
                    addedButtonGroupArrData.append(s + "#");
                }
                tButton.setAddedButtonGroupArrData(addedButtonGroupArrData.toString());
            }

//            List<Map<String, String>> returnValueArr = (List<Map<String, String>>) buttonOb.get("returnValueArr");
//            if (returnValueArr == null || returnValueArr.size() == 0) {
//                save(tButton);
//                buttonIdMapClickCommandList.put(tButton.getId(), clickCommandList);
//                return;
//            }
//            StringBuilder returnValueArrStr = new StringBuilder();
//            for (Map<String, String> stringStringMap : returnValueArr) {
//                returnValueArrStr.append(stringStringMap.get("valueName") + "#");
//            }
            save(tButton);
            buttonIdMapClickCommandList.put(tButton.getId(), clickCommandList);
            buttonIdMapInitCommandList.put(tButton.getId(), initCommandList);
        });
        Runnable runnable = new Runnable() {
            public void run() {
                tCommandService.saveCommandList("BUTTON", "click", buttonIdMapClickCommandList);
                tCommandService.saveCommandList("BUTTON", "init", buttonIdMapInitCommandList);
            }
        };
        new Thread(runnable).start();
    }


    /**
     * @author: fengweijie
     * @methodsName: deleteButtonByPageId
     * @description: 通过页面编号删除对应的按钮
     * @param: pageId
     * @return: String
     * @throws:
     */
    @Override
    public void deleteButtonByPageId(Integer pageId) {
        List<TButton> list = lambdaQuery()
                .select(TButton::getId)
                .eq(TButton::getPageId, pageId)
                .list();
        Set<Integer> btnIds = list.stream().map(TButton::getId).collect(Collectors.toSet());
        QueryWrapper<TButton> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda().eq(TButton::getPageId, pageId);
        remove(deleteWrapper);
        tCommandService.delCommandsByMain(btnIds, "BUTTON");
    }

    /**
     * @author: fengweijie
     * @methodsName: getButtonsByPageId
     * @description: 上传文件到服务器
     * @param: pageId，pageWidth，pageHeight，aimPageWidth，aimPage
     * @return: String
     * @throws:
     */
    @Override
    public List<TButton> getButtonsByPageId(Integer pageId, Double pageWidth, Double pageHeight, Double aimPageWidth, Double aimPageHeight, Boolean display) throws JsonProcessingException {
        List<TButton> btns = lambdaQuery()
                .eq(TButton::getPageId, pageId)
                .list();
        for (TButton btn : btns) {


            if (aimPageHeight != -1 && aimPageWidth != -1) {
                Double sourceBtnWidth = btn.getW();
                btn.setW(Math.floor((btn.getW() * aimPageWidth) / pageWidth));
                btn.setH(Math.floor((btn.getH() * aimPageHeight) / pageHeight));
                btn.setX(Math.floor((btn.getX() * aimPageWidth) / pageWidth));
                btn.setY(Math.floor((btn.getY() * aimPageHeight) / pageHeight));
                btn.setFontSize((int) Math.floor((btn.getFontSize()*btn.getW())/sourceBtnWidth));
            }


            btn.setConditionShow(btn.getConditionShowData() == null ? false : btn.getConditionShowData() == 1);

            List<TCommand> clickCommands = tCommandService.getCommandListByMain(btn.getId(), btn.getType(), "click");
            clickCommands = tCommandService.fillTCommands(clickCommands);

            Set<String> returnVariableSet = new HashSet<>();
            if (!CollectionUtils.isEmpty(clickCommands)){
                for (TCommand tCommand : clickCommands) {
                    List<Map<String, String>> returnValueArr = tCommand.getReturnValueArr();
                    if (!CollectionUtils.isEmpty(returnValueArr)) {
                        Set<String> valueNames = returnValueArr.stream().map(valueMap -> {
                            return valueMap.get("valueName");
                        }).collect(Collectors.toSet());

                        returnVariableSet.addAll(valueNames);
                    }
                    String beChangedVariableName = tCommand.getBeChangedVariableName();
                    if (!StringUtils.isEmpty(beChangedVariableName)) {
                        btn.setBeChangedVariableName(beChangedVariableName);
                    }
                }
            }
            btn.setReturnVariableSet(returnVariableSet);

            if (!display) {
                String logicGraphData = btn.getLogicGraphData();
                if (!StringUtils.isEmpty(logicGraphData)) {
                    ObjectMapper mapper = new ObjectMapper();
                    Map map = mapper.readValue(logicGraphData, Map.class);
                    btn.setLogicGraph(map);
                }
//                clickCommands = tCommandService.fillTCommands(clickCommands);
                String addedButtonGroupArrData = btn.getAddedButtonGroupArrData();
                if (!StringUtils.isEmpty(addedButtonGroupArrData)) {
                    ArrayList<String> addedButtonGroupArr = new ArrayList<>();
                    String[] split = addedButtonGroupArrData.split("#");
                    for (String s : split) {
                        addedButtonGroupArr.add(s);
                    }
                    btn.setAddedButtonGroupArr(addedButtonGroupArr);
                } else {
                    btn.setAddedButtonGroupArr(Collections.EMPTY_LIST);
                }
                btn.setClickCommandList(clickCommands);
            } else {
                btn.setLogicGraphData(null);
            }
        }
        return btns;
    }

    /**
     * @param pageId
     * @return List
     * @Description: 根据页面ID获取按钮ID
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:14
     */
    @Override
    public List<TButton> getButtonIdsByPageId(Integer pageId) {
        List<TButton> tButtons = lambdaQuery()
                .select(TButton::getId)
                .eq(TButton::getPageId, pageId)
                .list();
        return tButtons;
    }

    /**
     * @param conditionMap
     * @param ip
     * @Description: 执行指令
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:16
     */
    @Override
    public void executeCommand(Map<String, Object> conditionMap, String ip) throws EncodeException, IOException {
        Map<String, Object> variableMap = (Map<String, Object>) conditionMap.get("variableSet");
        String wsToken = conditionMap.get("wsToken").toString();
        TButton tButton = getById(Integer.parseInt(conditionMap.get("id").toString()));
        List<TCommand> commandList = tCommandService.getCommandListByMain(tButton.getId(), tButton.getType(), "click");
         tCommandService.executeCommandsAndGetReply(commandList, variableMap, wsToken,ip);

    }

    /**
     * @param mainId
     * @return Integar
     * @Description: 根据按钮ID获取页面ID
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:16
     */
    @Override
    public Integer getPageIdByButtonId(Integer mainId) {
        TButton byId = getById(mainId);
        return byId.getPageId();
    }


    public static int countCharOccurrences(String input, char targetChar) {
        return input.length() - input.replace(String.valueOf(targetChar), "").length();
    }

}
